package com.gitee.wsl.mathematics.vector.ext

import com.gitee.wsl.mathematics.vector.vec2.Vec2f
import com.gitee.wsl.mathematics.vector.vec3.Vec3f
import com.gitee.wsl.mathematics.vector.vec4.Vec4f
import kotlin.math.ln
import kotlin.math.sqrt
import kotlin.random.Random

fun gaussian(mean: Double = 0.0, deviation: Double = 1.0, random: Random = Random.Default): Double {
    var v1: Double
    var v2: Double
    var s: Double
    do {
        v1 = 2 * random.nextDouble() - 1
        v2 = 2 * random.nextDouble() - 1
        s = v1 * v1 + v2 * v2
    } while (s >= 1 || s == 0.0)
    val multiplier = sqrt(-2 * ln(s) / s)

    return v1 * multiplier * deviation + mean
}

fun gaussian(mean: Float = 0.0f, deviation: Float = 1.0f, random: Random = Random.Default): Float = gaussian(mean.toDouble(),deviation.toDouble(),random).toFloat()

/*fun Double.Companion.gaussian(
    mean: Double = 0.0,
    deviation: Double = 1.0,
    random: Random = Random.Default
): Double = gaussian(mean, deviation, random)*/

fun  Vec2f.Companion.gaussian(mean: Vec2f = Vec2f.ZERO, deviation: Vec2f = Vec2f.ONE, random: Random = Random.Default): Vec2f {
    return Vec2f(gaussian(mean.x, deviation.x, random), gaussian(mean.y, deviation.y, random))
}

fun Vec3f.Companion.gaussian(mean: Vec3f = Vec3f.ZERO, deviation: Vec3f = Vec3f.ONE, random: Random = Random.Default): Vec3f {
    return Vec3f(
        gaussian(mean.x, deviation.x, random),
        gaussian(mean.y, deviation.y, random),
        gaussian(mean.z, deviation.z, random))
}

fun Vec4f.Companion.gaussian(mean: Vec4f = Vec4f.ZERO, deviation: Vec4f = Vec4f.ONE, random: Random = Random.Default): Vec4f {
    return Vec4f(
        gaussian(mean.x, deviation.x, random),
        gaussian(mean.y, deviation.y, random),
        gaussian(mean.z, deviation.z, random),
        gaussian(mean.w, deviation.w, random))
}